﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using MoneyWentWhere.Utils;
using System.Collections;

namespace MoneyWentWhere.OutputHelpers
{
    public class DictionaryColumn : MultiColumn
    {
        readonly FieldInfo DictionaryField;

        public DictionaryColumn(TableOptions options, FieldInfo dictionaryField)
            : base(options)
        {
            DictionaryField = dictionaryField;
        }

        // Examine each Dictionary
        //   Get the set of ALL keys
        //   Create subcolumns for each key, populate
        // Total width = sum(subcolumns.Width)

        protected override void InitializeSubcolumns<T>(IEnumerable<T> rows)
        {
            // Get the list of dictionaries
            List<IDictionary> dics = new List<IDictionary>();
            foreach (T row in rows)
            {
                IDictionary dic = (IDictionary)DictionaryField.GetValue(row);
                dics.Add(dic);
            }

            var keys = dics
                .SelectMany(dic => dic.Keys.Cast<object>())
                .Distinct()
                .OrderBy(x => x); // natural order

            // Subcolumn for each key
            Columns = new List<Column>();
            foreach (object key in keys)
            {
                Column subCol = new DictionaryValueColumn(TableOptions, DictionaryField, key);
                Columns.Add(subCol);
            }
        }
    }

    public class DictionaryValueColumn : ValueColumn
    {
        readonly FieldInfo DictionaryField;
        readonly object Key;

        public DictionaryValueColumn(TableOptions options, FieldInfo dictionaryField, object key)
            : base(options, dictionaryField)
        {
            DictionaryField = dictionaryField;
            Key = key;

            DisplayConverter headerConverter = GetHeaderConverter(dictionaryField);
            Header = headerConverter.FieldToString(key);
        }

        static DisplayConverter GetHeaderConverter(MemberInfo member)
        {
            HeaderDisplayConverterAttribute att = member.GetAttribute<HeaderDisplayConverterAttribute>();
            if (att == null)
            {
                return new DefaultDisplayConverter();
            }
            else
            {
                return (DisplayConverter)Activator.CreateInstance(att.ConverterType);
            }
        }


        public override object GetValue<T>(T row)
        {
            IDictionary dict = (IDictionary)DictionaryField.GetValue(row);
            if (dict.Contains(Key)) 
            {                 
                return dict[Key];
            }
            return null;
        }

    }
}
